查看原文
其他

@ccclass 这是什么!TypeScirpt 类装饰器!浅谈它在 cocos creator 做了什么!

lamyoung 白玉无冰 2022-06-10

点击上方蓝字关注我吧

在 cocos creator - typescirpt 项目中,添加一个类(class)时,前面会有一个 @ccclass,这个是什么呢?


类装饰器

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。装饰器使用 @expression 这种形式,expression 求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。

cocos creator 中的 @ccclass 是附加在class之前的,是一个类装饰器。类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。


declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;

上面是类装饰器的定义,target 就是该类的构造函数。如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。如果你要返回一个新的构造函数,你必须注意处理好原来的原型链。 在运行时的装饰器调用逻辑中不会为你做这些。

可以一起看下面的例子


const decorator: ClassDecorator = function (target: Function) {
    console.log('调用装饰器')
    const oldGreet = target.prototype.greet
    target.prototype.greet = function () {
        return "欢迎关注 " + oldGreet.call(this);
    }
}

console.log('定义类')
@decorator
class Greeter {
    greeting: string;
    constructor(message: string) {
        console.log('Greeter constructor')
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}
console.log('实例化类')
let greeter = new Greeter("白玉无冰");
console.log(greeter.greet())

输出结果


定义类
调用装饰器
实例化类
Greeter constructor
欢迎关注 Hello, 白玉无冰

可以看到,在声明类前,装饰器就对类进行修改。


@ccclass

接着,一起看下ccclass 里做了什么。


function checkCtorArgument (decorate) {
    return function (target) {
        if (typeof target === 'function') {
            // no parameter, target is ctor
            return decorate(target);
        }
        return function (ctor) {
            return decorate(ctor, target);
        };
    };
}

var ccclass = checkCtorArgument(function (ctor, name) {
    var base = js.getSuper(ctor);
    if (base === Object) {
        base = null;
    }

    var proto = {
        name,
        extends: base,
        ctor,
        __ES6__: true,
    };

    // mixi ...

    var res = cc.Class(proto);

    // validate methods
    // ...

    return res;
});

可以看到,ccclass 采用了函数柯里化的写法,ccclass可以接收一个或零个参数,通过第一个参数的类型判断,来传给真正的类装饰器 function (ctor, name) {//...}


// define a CCClass, omit the name
@ccclass
class NewScript extends cc.Component {
    // ...
}
  
// define a CCClass with a name
@ccclass('LoginData')
class LoginData {
    // ...
}

在类装饰器里,调用 cc.Class   创建新的构造函数,替换原来的构造函数,并对原型链做了处理。


结语

cocos creator 中的 @ccclass 里的实现,原理大致上是把ts中定义类转成js中cc.class的实现写法。

以上是自己的浅谈,如有错误的地方,欢迎斧正。


有你想看的精彩 在 2.0.9 之前版本使用 tween!
微信小游戏流量主广告接入指南!
cocos creator | 残影幻影拖尾效果
不仅要提升挣钱能力,更要拓展挣钱途径


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存